package com.shitou.shitoumember.service.impl;

import com.shitou.shitoucommons.exception.RRException;
import com.shitou.shitoucommons.utils.*;
import com.shitou.shitoucommons.vo.MessageVo;
import com.shitou.shitoumember.service.MemberService;
import com.shitou.shitoumember.service.SendReceiveService;
import com.shitou.shitoumember.vo.MemberInfoVo;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import com.shitou.shitoumember.dao.MemberExchangeDao;
import com.shitou.shitoumember.entity.MemberExchangeEntity;
import com.shitou.shitoumember.service.MemberExchangeService;

import javax.annotation.Resource;
import javax.xml.crypto.Data;

@SuppressWarnings("all")
@Transactional
@Service("memberExchangeService")
public class MemberExchangeServiceImpl extends ServiceImpl<MemberExchangeDao, MemberExchangeEntity> implements MemberExchangeService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberExchangeEntity> page = this.page(
                new Query<MemberExchangeEntity>().getPage(params),
                new QueryWrapper<MemberExchangeEntity>()
        );

        return new PageUtils(page);
    }

    @Resource
    private MemberService memberService;

    @Resource
    private SendReceiveService sendReceiveService;


    /**
     * 创建信息，，，多个接口调用创建信息
     * @param messageVo 信息
     * @param off_line 是否是离线消息，true/false  1/0
     * @param isMessaging 是否是站内信消息 true/false 1/0
     */
    public void insertMessage(MessageVo messageVo, boolean off_line, boolean isMessaging){

        // 校验是否合法
//        CensorVo censorVo = TextCensor.TextCensor(messageVo.getText());
//        if (censorVo.getConclusion().equals("不合规") || censorVo.getConclusionType().equals("2")){
//            throw new RRException("输入信息不合法,内有违规信息");
//        }

        // 如果只是单纯的插入离线消息或者站内信，那么直接插入
        if ( off_line || isMessaging ){
            // 单纯就是新的消息，，进行插入
            MemberExchangeEntity exchangeEntity = new MemberExchangeEntity();
            Date date = new Date();
            exchangeEntity.setCreateTime(date);
            exchangeEntity.setUpdateTime(date);
            exchangeEntity.setSendMemberId(Long.valueOf(messageVo.getFrom()));
            exchangeEntity.setReceiveMemberId(Long.valueOf(messageVo.getTo()));
            exchangeEntity.setStatus(1);
            exchangeEntity.setContent(messageVo.getText());
            // 判断是否是离线消息
            if ( off_line ){
                exchangeEntity.setOffLine(1);
            }else {
                exchangeEntity.setOffLine(0);
            }
            // 判断是否是站内消息
            if ( isMessaging ){
                exchangeEntity.setMessaging(1);
            }else {
                exchangeEntity.setMessaging(0);
            }
            baseMapper.insert(exchangeEntity);

        }else {
            // 将该站内信或者多个站内信转换为已经读取的
            checkMessaging(messageVo);
            // 将单个离线或者多个离线消息转换为在线消息，说明已读
            checkOffLine(messageVo);
        }
    }


    /**
     * 站内信判断
     * @return
     */
    public boolean checkMessaging(MessageVo messageVo){
        // 如果该信息是离线信息又是站内信，那么将离线信息改为在线消息，说明已经被读过了,,由于可能发了多句相同的
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("send_member_id", messageVo.getFrom())
                .eq("receive_member_id", messageVo.getTo())
                .eq("content", messageVo.getText())
                .eq("off_line", 1)
                        .eq("status", 1)
                .eq("messaging", 1));// 站内信
        return checkAll(list);
    }


    /**
     * 离线信息判断
     * @return
     */
    public boolean checkOffLine(MessageVo messageVo){
        // 查找该消息是否是离线消息，如果有，则将该消息转换为在线消息，,,由于可能发了多句相同的
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("send_member_id", messageVo.getFrom())
                .eq("receive_member_id", messageVo.getTo())
                .eq("content", messageVo.getText())
                .eq("off_line", 1)
                        .eq("status", 1)
                .eq("messaging", 0));// 排除站内信
        return checkAll(list);
    }


    public boolean checkAll(List<MemberExchangeEntity> list){
        if ( list != null && list.size() > 0){
            Date date = new Date();
            Iterator<MemberExchangeEntity> iterator = list.iterator();
            while( iterator.hasNext() ){
                MemberExchangeEntity next = iterator.next();
                next.setOffLine(0);
                next.setUpdateTime(date);
            }
            this.updateBatchById(list);
            return true;
        }
        return false;
    }

    /**
     * 交流时，将信息存入到数据库
     * @param messageVo
     * @see MessageVo
     * @return
     */
    @Override
    public RespBean createExchange(MessageVo messageVo) {
        insertMessage(messageVo, false, false);
        return RespBean.success();
    }


    /**
     * 删除当前会员的所对应的接收者的信息
     * @param memberId 发送者id
     * @param receiveMemberId 接收者id
     * @return
     */
    @Override
    public RespBean deleteExchange(Long memberId, Long receiveMemberId) {
        if ( memberId == null || memberId == 0 ){
            throw new RRException("用户信息异常");
        }
        if ( receiveMemberId == null || receiveMemberId == 0 ){
            throw new RRException("用户信息异常");
        }
        // 获取信息list
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("receive_member_id", receiveMemberId)
                .eq("send_member_id", memberId)
                        .eq("status", 1)
                .eq("messaging", 0));  // 排除站内信

        // 获取idS
        List<Long> idS = new ArrayList<>();
        for (MemberExchangeEntity exchangeEntity : list) {
            idS.add(exchangeEntity.getId());
        }
        try {
            // 删除
            this.removeByIds(idS);
        } catch (Exception e) {
            throw new RRException("删除信息失败");
        }

        return null;
    }


    /**
     * 创建离线消息
     * @param messageVo
     * @return
     */
    @Override
    public RespBean createOffLine(MessageVo messageVo) {
        insertMessage(messageVo, true, false);
        return RespBean.success();
    }


    /**
     * 通过会员id获取该会员的所有离线消息
     * @param memberId
     * @return
     */
    @Override
    public List<MessageVo> getOffLineMessage(Long memberId) {
        // 获取该用户的所有的离线消息
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("receive_member_id", memberId)   // 接收者id,,,自己是接收者，别人发过来的信息
                .eq("off_line", 1)    // 离线消息
                        .eq("status", 1)
                .eq("messaging", 0));    // 排除站内信
        if ( list == null && list.size() <= 0 ){
            return null;
        }
        return getMessageVo(list, memberId);
    }


    /**
     * 获取当前会员和另一个会员的聊天记录
     * @param memberId
     * @param receiveMemberId
     * @return
     */
    @Override
    public RespBean getMemberExchange(Long memberId, Long receiveMemberId) {
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("send_member_id", memberId)
                .eq("receive_member_id", receiveMemberId)
                .eq("messaging", 0)// 排除站内信
                        .eq("status", 1)
                .or(new Consumer<QueryWrapper<MemberExchangeEntity>>() {
                    @Override
                    public void accept(QueryWrapper<MemberExchangeEntity> memberExchangeEntityQueryWrapper) {
                        memberExchangeEntityQueryWrapper
                                .eq("send_member_id", receiveMemberId)
                                .eq("receive_member_id", memberId);
                    }
                }));

        return RespBean.success().put("data", list.stream().filter(exchange->{
            return exchange.getMessaging().equals(0);
        }).sorted((item, item1)->{
            return (int) (item.getUpdateTime().getTime() - item1.getUpdateTime().getTime());
        }).collect(Collectors.toList()));
    }


    /**
     * 获得当前登录会员与之聊天的人的列表
     * @param memberId
     * @return
     */
    @Override
    public RespBean getChatNumber(Long memberId) {

        RespBean respbean1 = sendReceiveService.getMemberReceive(memberId);
        List<Long> list = (List<Long>) respbean1.get("data");

        List<MemberInfoVo> memberInfoVos = new ArrayList<>();

        MemberInfoVo memberInfoVo = null;
        for (Long id : list) {
            // 通过id获取数据
            RespBean respBean = memberService.getMemberByMemberId(id);
            memberInfoVo = (MemberInfoVo) respBean.get("data");
            memberInfoVos.add(memberInfoVo);
        }
        return RespBean.success().put("data", memberInfoVos);
    }


    /**
     * 远程调用，构建站内信
     * @param memberId 发送者id
     * @param receiveMemberId 接收者id
     * @return
     */
    @Override
    public RespBean createMessaging(MessageVo messageVo) {

        insertMessage(messageVo, true, true);
        return RespBean.success();
    }


    /**
     * 获得登录用户的所有站内信信息
     * @param memberId
     * @return
     */
    @Override
    public RespBean getMessaging(Long memberId) {
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("receive_member_id", memberId)   // 接收者是自己
                .eq("status", 1)
                .eq("messaging", 1));    // 选择站内信
        if ( list == null && list.size() <= 0 ){
            return null;
        }
        // 根据是否已读排序，未读在后
        list = list.stream().sorted((a,b)->{
            return b.getOffLine() - a.getOffLine();
        }).collect(Collectors.toList());
        list = list.stream().sorted((a,b)->{
            return (int) (b.getCreateTime().getTime() - a.getCreateTime().getTime());
        }).collect(Collectors.toList());
        return RespBean.success().put("data", list);
    }


    /**
     * 统计未读取的站内信数量
     * @param memberId
     * @return
     */
    @Override
    public RespBean messagingCount(Long memberId) {
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("receive_member_id", memberId)   // 接收者是自己
                .eq("off_line", 1)       // 站内信也是离线消息
                .eq("status", 1)
                .eq("messaging", 1));    // 选择站内信
        return RespBean.success().put("data", list.size());
    }


    /**
     * 获取信息实体类，通过用户信息list
     * @param list
     * @param memberId
     * @return
     */
    private List<MessageVo> getMessageVo(List<MemberExchangeEntity> list, Long memberId){
        List<MessageVo> messageVoList = new ArrayList<>();

        Iterator<MemberExchangeEntity> iterator = list.iterator();
        while( iterator.hasNext() ){
            MemberExchangeEntity exchangeEntity = iterator.next();
            exchangeEntity.setOffLine(1);
            MessageVo messageVo = new MessageVo();
            messageVo.setDate(exchangeEntity.getCreateTime());
            messageVo.setFrom(String.valueOf(exchangeEntity.getSendMemberId()));
            messageVo.setTo(String.valueOf(memberId));
            messageVo.setText(exchangeEntity.getContent());
            messageVoList.add(messageVo);
        }

        return messageVoList;
    }


    /**
     * 通过信息的id获取信息，，主要用于读取站内信操作
     * @param messagingId
     * @return
     */
    @Override
    public MessageVo getMessageVoById(Long messagingId, Long memberId) {
        List<MemberExchangeEntity> list = this.list(new QueryWrapper<MemberExchangeEntity>()
                .eq("id", messagingId)
                .eq("receive_member_id", memberId)
                .eq("status", 1));

        MemberExchangeEntity exchangeEntity = list.get(0);
        // 如果该站内信是退款的。。。那么修改样式
        String text = exchangeEntity.getContent();
        if ( text.indexOf("id=\"refundOption\"") != -1 ){
            text = text.replaceAll("pointer-events: all;", "pointer-events: none;");
            text = text.replaceAll("cursor: pointer;", "cursor: not-allowed");
            // 更新
            exchangeEntity.setContent(text);
            this.updateById(exchangeEntity);
            list = this.list(new QueryWrapper<MemberExchangeEntity>()
                    .eq("id", messagingId)
                    .eq("receive_member_id", memberId)
                    .eq("status", 1));
        }

        return getMessageVo(list, memberId).get(0);
    }


    /**
     * 删除站内信
     * @param memberId
     * @param messagingId
     * @return
     */
    @Override
    public RespBean deleteMessaging(Long memberId, Long messagingId) {
        MemberExchangeEntity one = this.getOne(new QueryWrapper<MemberExchangeEntity>()
                .eq("receive_member_id", memberId)
                .eq("status", 1)
                .eq("id", messagingId)
                .eq("messaging", 1));
        one.setStatus(0);
        one.setUpdateTime(new Date());
        this.updateById(one);

        return RespBean.success();
    }


}
